<html>
<head>
<title>CpcPaChi - Version 0.05</title>
<style type="text/css">
span {
	font-family: 'Courier New';
	font-size: 10pt;
	color: #000000;
}
.sc0 {
	color: #808080;
}
.sc3 {
	color: #008080;
}
.sc4 {
	color: #FF8000;
}
.sc5 {
	font-weight: bold;
	color: #0000FF;
}
.sc7 {
	color: #808080;
}
.sc9 {
	color: #804000;
}
.sc10 {
	font-weight: bold;
	color: #000080;
}
.sc11 {
}
</style>
</head>
<body>
<h2>Un compilador sencillo paso a paso (5)</h2>

<p align="right">(Volver al <a href="doc.html">&iacute;ndice</a>) </p>

<p>En el quinto acercamiento vamos a reconocer una estructura algo m&aacute;s parecida
a un fuente "real" en pascal, que comience con "program" y tenga un cuerpo
de programa delimitado ente "begin" y "end", incluso con espacios en blanco,
como &eacute;sta:</p>

<pre><code>
program ej;
begin
 &nbsp;cls;
 &nbsp;locate(10,5);
 &nbsp;writeChar( 'a' );
 &nbsp;locate ( 1 ,  10 );
 &nbsp;writeChar('c');
end.
</code></pre>

<p>Esto supone dos cambios:</p>

<ul>
  <li>Vamos a sacar del cuerpo del programa lo que ser&aacute; el "analizador
    sint&aacute;ctico", el encargado de indicar en qu&eacute; orden deben estar los
    elementos del programa (por ejemplo: despu&eacute;s de "program" debe aparecer
    un identificador y un punto y coma, luego "begin" y una secuencia
    de &oacute;rdenes, etc).</li>
  <li>Ampliaremos un poco el analizador l&eacute;xico para que sea capaz
    de "saltarse" los espacios en blanco.</li>
</ul>

<p>En cuanto al "analizador sint&aacute;ctico", simplemente ampliamos el anterior
"analizarCualquierOrden", que ahora estar&aacute; dentro de un "analizarPrograma",
que se asegura de que antes aparezca program, begin, etc, as&iacute;:</p>

<pre><code>
procedure analizarPrograma;
begin
  (* program &lt;identificador&gt;; *)
  orden := upcase(obtenerIdentificador);
  if orden &lt;&gt; 'PROGRAM' then
    begin
    writeln('No se ha encontrado PROGRAM');
    halt;
    end;
  obtenerIdentificador;
  leerSimbolo(';');

  (* begin *)
  orden := upcase(obtenerIdentificador);
  if orden &lt;&gt; 'BEGIN' then
    begin
    writeln('No se ha encontrado BEGIN');
    halt;
    end;

  (* Resto de ordenes *)
  while not finFicheroEntrada do
    begin
    analizarCualquierOrden;
    end;
end;
</code></pre>

<p><br>Por lo que respecta al analizador l&eacute;xico, cada vez que vayamos a leer
un identificador, un entero o a esperar un s&iacute;mbolo concreto, deberemos
antes saltar los espacios en blanco que pudiera haber:</p>


<pre><code>
function obtenerIdentificador: string;
var
  lexema: string;
  letra: char;
begin
  saltarBlancos;
  lexema := '';
  letra := obtenerLetra;
  [...]
  
procedure saltarBlancos;
begin
  while (lineaDeEntrada[posicionLineaActual+1] in espacioBlanco) do
    obtenerLetra;
end;

espacioBlanco: set of char =  [chr(32), chr(10), chr(13)];
</code></pre>

<p><br>Para m&aacute;s detalles, todo el c&oacute;digo est&aacute; en la p&aacute;gina del proyecto en Google Code:<br /><br /><a href="http://code.google.com/p/cpcpachi/">http://code.google.com/p/cpcpachi/</a></p>



<p align="right">(Volver al <a href="doc.html">&iacute;ndice</a>) </p>
</body>
</html>
